home *** CD-ROM | disk | FTP | other *** search
- ; 64-bit x 64-bit unsigned divide
- ; Compact but stupid algorithm
- ;
- ; Tim Victor, December 28, 1992
- ;
- ; Callable from C as follows:
- ; int ExtDivB(dividend, divisor, quotient, remainder);
- ; returns 1 for attempted divide-by-zero, 0 otherwise
- ;
-
- .model small
- .code
- public _ExtDivB
- _ExtDivB proc near
-
- push bp ; save caller's stack frame
- mov bp,sp ; address stack frame of this call
- push si
- push di
-
- ; point si to divisor, zero-test
- mov si,[bp+6]
- mov ax,[si]
- or ax,[si+2]
- or ax,[si+4]
- or ax,[si+6]
-
- ;signal divide-by-zero, bail if error
- mov ax,1 ; no effect on flags
- jz exithere
-
- ; point di to quotient storage, copy in dividend
- mov di,[bp+8]
- mov bx,[bp+4]
-
- mov ax,[bx]
- mov [di],ax
- mov ax,[bx+2]
- mov [di+2],ax
- mov ax,[bx+4]
- mov [di+4],ax
- mov ax,[bx+6]
- mov [di+6],ax
-
- ; clear 64-bit accumulator (bp:dx:bx:ax)
- push bp
- sub ax,ax
- mov bx,ax
- mov dx,ax
- mov bp,ax
-
- ; init counter for 64 loop iterations
- mov cx,64
-
- divloop:
- ; shift high bit out of dividend
- shl word ptr [di],1
- rcl word ptr [di+2],1
- rcl word ptr [di+4],1
- rcl word ptr [di+6],1
-
- ; shift bit into accumulator
- rcl ax,1
- rcl bx,1
- rcl dx,1
- rcl bp,1
-
- ; compare divisor to accum
- cmp bp, [si+6]
- jb nosub
- ja subdiv
-
- cmp dx, [si+4]
- jb nosub
- ja subdiv
-
- cmp bx, [si+2]
- jb nosub
- ja subdiv
-
- cmp ax, [si]
- jb nosub
-
- subdiv:
- ; if accum > divisor, subtract divisor
- sub ax, [si]
- sbb bx, [si+2]
- sbb dx, [si+4]
- sbb bp, [si+6]
-
- ; put a one bit in quotient
- inc word ptr [di]
-
- nosub:
- loop divloop
-
- ; done, store remainder
- pop si ; get call frame addr
- mov si,[si+0Ah] ; addr of remainder
- mov [si],ax
- mov [si+2],bx
- mov [si+4],dx
- mov [si+6],bp
-
- ; signal success
- sub ax,ax
-
- ; restore caller's regs
- exithere:
- pop di
- pop si
- pop bp
-
- ret
-
- _ExtDivB endp
- end
-
-